package ua.org.extjsbuilder.parser.runtime;

import ua.org.extjsbuilder.parser.IInstruction;
import ua.org.extjsbuilder.parser.runtime.data.JSNumber;
import ua.org.extjsbuilder.parser.runtime.data.JSString;
import ua.org.extjsbuilder.parser.runtime.instructions.BinaryOperator;
import ua.org.extjsbuilder.parser.runtime.instructions.Breaker;
import ua.org.extjsbuilder.parser.runtime.instructions.Condition;
import ua.org.extjsbuilder.parser.runtime.instructions.Declare;
import ua.org.extjsbuilder.parser.runtime.instructions.GetEntity;
import ua.org.extjsbuilder.parser.runtime.instructions.TryCatchFinally;

public class ConditionsInterpreterTestCase extends AbstractInterpreterTestCase {

	@Override
	protected String getMockPkg() {
		return "ua/org/extjsbuilder/parser/runtime/conditions/";
	}
	
	public void testIf() throws Exception {
		IInstruction cond = parseFile("if1.js", Declare.class, Condition.class).get(1);
		assertEquals(Condition.class,cond.getClass());
		Condition condition = (Condition)cond;
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock());
		
		cond = parseFile("if2.js", Declare.class, Condition.class).get(1);
		assertEquals(Condition.class,cond.getClass());
		condition = (Condition)cond;
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock(), Declare.class);
		
		cond = parseFile("if3.js", Declare.class, Declare.class, Condition.class).get(2);
		assertEquals(Condition.class,cond.getClass());
		condition = (Condition)cond;
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock(), Condition.class);
		
		condition = (Condition)condition.getElseBlock().get(0);
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock(), Declare.class);
		
		cond = parseFile("if4.js", Declare.class, Condition.class, Condition.class).get(2);
		assertEquals(Condition.class,cond.getClass());
		condition = (Condition)cond;
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock(), Declare.class);
		
		cond = parseFile("if5.js", Declare.class, Condition.class).get(1);
		assertEquals(Condition.class,cond.getClass());
		condition = (Condition)cond;
		assertEquals(Condition.TYPE_IF,condition.getName());
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		assertInstructions(condition.getMainBlock(), Declare.class);
		assertInstructions(condition.getElseBlock());
	}
	
	public void testSwitch() throws Exception{
		IInstruction cond = parseFile("switch1.js", Declare.class, Condition.class).get(1);
		assertEquals(Condition.class,cond.getClass());
		Condition condition = (Condition)cond;
		assertEquals(Condition.TYPE_SWITCH,condition.getName());
		assertEquals(5, condition.getCases().size());
		assertInstructions(condition.getCases().get(new JSNumber(1)), 
				Declare.class, Declare.class, Breaker.class);
		assertInstructions(condition.getCases().get(null), Breaker.class);
		assertEquals(GetEntity.class,condition.getCondition().getClass());
		
		cond = parseFile("switch2.js", Declare.class, Condition.class).get(1);
		assertEquals(Condition.class,cond.getClass());
		condition = (Condition)cond;
		assertEquals(Condition.TYPE_SWITCH,condition.getName());
		assertEquals(4, condition.getCases().size());
		assertInstructions(condition.getCases().get(new JSString("vvv")), 
				Declare.class, Declare.class, Condition.class, Breaker.class);
		
		Condition ifCond = (Condition)condition.getCases()
					.get(new JSString("vvv")).get(2);
		assertInstructions(ifCond.getMainBlock(),Declare.class);
		assertInstructions(ifCond.getElseBlock());
	}
	
	public void testTryCatch() throws Exception{
		IInstruction cond = parseFile("try1.js", TryCatchFinally.class).get(0);
		assertEquals(TryCatchFinally.class,cond.getClass());
		TryCatchFinally condition = (TryCatchFinally)cond;
		
		assertInstructions(condition.getTryBlock(), BinaryOperator.class,
				BinaryOperator.class,BinaryOperator.class);
		assertInstructions(condition.getCatchBlock(), BinaryOperator.class);
		assertInstructions(condition.getFinallyBlock(), BinaryOperator.class);
		assertEquals("e", condition.getErrorName());
		
		cond = parseFile("try2.js", TryCatchFinally.class).get(0);
		assertEquals(TryCatchFinally.class,cond.getClass());
		condition = (TryCatchFinally)cond;
		
		assertInstructions(condition.getTryBlock(), BinaryOperator.class,
				BinaryOperator.class,BinaryOperator.class);
		assertInstructions(condition.getCatchBlock(), BinaryOperator.class);
		assertEquals("e", condition.getErrorName());
		assertNull(condition.getFinallyBlock());
		
		cond = parseFile("try3.js", TryCatchFinally.class).get(0);
		assertEquals(TryCatchFinally.class,cond.getClass());
		condition = (TryCatchFinally)cond;
		
		assertInstructions(condition.getTryBlock(), BinaryOperator.class,
				BinaryOperator.class,BinaryOperator.class);
		assertNull(condition.getCatchBlock());
		assertNull(condition.getErrorName());
		assertInstructions(condition.getFinallyBlock(), BinaryOperator.class);
	}
}
